import java.util.Comparator;

public class Point  implements Comparable<Point>{

    private final int x;     // x-coordinate of this point
    private final int y;     // y-coordinate of this point

    /**
     * Initializes a new point.
     *
     * @param  x the <em>x</em>-coordinate of the point
     * @param  y the <em>y</em>-coordinate of the point
     */
    public Point(int x, int y) {
        /* DO NOT MODIFY */
        this.x = x;
        this.y = y;
    }

   
    /**
     * Returns the slope between this point and the specified point.
     * Formally, if the two points are (x0, y0) and (x1, y1), then the slope
     * is (y1 - y0) / (x1 - x0). For completeness, the slope is defined to be
     * +0.0 if the line segment connecting the two points is horizontal;
     * Double.POSITIVE_INFINITY if the line segment is vertical;
     * and Double.NEGATIVE_INFINITY if (x0, y0) and (x1, y1) are equal.
     *
     * @param  that the other point
     * @return the slope between this point and the specified point
     */
    public double slopeTo(Point that) {
        /* YOUR CODE HERE */
        double slope=0;
        double dy=that.y-this.y;
        double dx=that.x-this.x;
        if(dx==dy&&dx==0)       //就是自己
        {
           slope=Double.NEGATIVE_INFINITY;
        }
        else if(dx==0)
        {
           slope=0;
        }
        else if(dy==0)
        {
           slope=Double.POSITIVE_INFINITY;
        }
        else
        {
           slope=dy/dx;
        }
        return slope;
    }

    /**
     * Compares two points by y-coordinate, breaking ties by x-coordinate.
     * Formally, the invoking point (x0, y0) is less than the argument point
     * (x1, y1) if and only if either y0 < y1 or if y0 = y1 and x0 < x1.
     *
     * @param  that the other point
     * @return the value <tt>0</tt> if this point is equal to the argument
     *         point (x0 = x1 and y0 = y1);
     *         a negative integer if this point is less than the argument
     *         point; and a positive integer if this point is greater than the
     *         argument point
     */
    public int compareTo(Point that) {
        /* YOUR CODE HERE */
        int dy=that.y-this.y;
        int dx=that.x-this.x;
        if(dy!=0)
        {
           if(dy>0)
           {
               return -1;
           }
           else
           {
               return 1;
           }
        }
        else if(dy==0&&dx!=0)
        {
            if(dx>0)
            {
                return -1;
            }
            else
            {
                return 1;
            }
        }
        else
        {
          return 0;
        } 
    }

    /**
     * Compares two points by the slope they make with this point.
     * The slope is defined as in the slopeTo() method.
     *
     * @return the Comparator that defines this ordering on points
     */
   public Comparator<Point> slopeOrder() {     //这里是返回一个比较器
       /* YOUR CODE HERE */
      return new Comparator<Point>() {
        public int compare(Point a,Point b)
        {
            return Double.compare(slopeTo(a),slopeTo(b));     
        }
      }; 
   }


    /**
     * Returns a string representation of this point.
     * This method is provide for debugging;
     * your program should not rely on the format of the string representation.
     *
     * @return a string representation of this point
     */
    public String toString() {
        /* DO NOT MODIFY */
        return "(" + x + ", " + y + ")";
    }

    @Override
     public boolean equals(Object obj) {
        if (this == obj) return true;  // 如果是同一个对象，直接返回true
        if (obj == null || getClass() != obj.getClass()) return false;  // 类型检查

        Point that = (Point) obj;  // 强制类型转换
        return this.x==that.x&&this.y==that.y;  // 比较id和name
    }

    /**
     * Unit tests the Point data type.
     */
    public static void main(String[] args) {
        /* YOUR CODE HERE */
      Point p=new Point(2,2);
      Point q=new Point(1,1);
      Point f=new Point(3,3);
      System.out.printf(p.toString());
      int a=q.compareTo(p);
      double b=q.slopeTo(p);
      Comparator<Point> c=p.slopeOrder();
      double aaa1=p.slopeTo(q);
      double aaa2=p.slopeTo(f);
      int d=c.compare(q, f);
      int sladj= p.compareTo(q);
    }
}